package com.pikaqiu.warehouse.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pikaqiu.warehouse.config.BaseContext;
import com.pikaqiu.warehouse.config.MiniConstant;
import com.pikaqiu.warehouse.domain.common.ReqCommonParams;
import com.pikaqiu.warehouse.domain.dto.UserDto;
import com.pikaqiu.warehouse.domain.entity.Company;
import com.pikaqiu.warehouse.domain.entity.User;
import com.pikaqiu.warehouse.domain.entity.UserCompany;
import com.pikaqiu.warehouse.domain.entity.UserToken;
import com.pikaqiu.warehouse.exception.MiniAuthException;
import com.pikaqiu.warehouse.mapper.UserMapper;
import com.pikaqiu.warehouse.service.CompanyService;
import com.pikaqiu.warehouse.service.UserCompanyService;
import com.pikaqiu.warehouse.service.UserService;
import com.pikaqiu.warehouse.service.UserTokenService;
import com.pikaqiu.warehouse.utils.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Administrator
* @createDate 2024-08-14 14:44:31
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Resource
    private UserTokenService userTokenService;

    @Resource
    private UserCompanyService userCompanyService;

    @Resource
    private CompanyService companyService;

    @Override
    public ReqCommonParams checkUser() {
        ReqCommonParams reqCommonParams = BaseContext.get();
        String token = reqCommonParams.getToken();
        if (StringUtils.isEmpty(token)) throw new MiniAuthException("请先登录");
        List<UserToken> userTokenList = userTokenService.list(new QueryWrapper<UserToken>()
            .eq("token", token).orderByDesc("create_date"));
        if (CollectionUtil.isEmpty(userTokenList)) throw new MiniAuthException("请先登录");
        UserToken userToken = userTokenList.get(0);
        Date expireDate = userToken.getExpireDate();
        if (DateUtil.compare(expireDate, DateUtil.date()) < 0) throw new MiniAuthException("登录已过期,请重新登录");
        User user = getById(userToken.getUserId());
        List<UserCompany> userCompanyList = userCompanyService.listUserCompanyId(user.getId());
        List<Integer> companyIdList = userCompanyList.stream().map(UserCompany::getCompanyId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(companyIdList)) {
            companyIdList.add(MiniConstant.DEFAULT_COMPANY_ID);
        }
        Integer companyId = userCompanyList.stream().filter(UserCompany::getCurrentFlag)
            .map(UserCompany::getCompanyId).findFirst().orElse(MiniConstant.DEFAULT_COMPANY_ID);
        Company company = companyService.getById(companyId);
        reqCommonParams.setUserId(user.getId());
        reqCommonParams.setNickName(user.getNickName());
        reqCommonParams.setCompanyId(companyId);
        reqCommonParams.setCompanyCode(company.getCode());
        reqCommonParams.setUserCompanyIdList(companyIdList);
        BaseContext.set(reqCommonParams);
        user.setLastActiveTime(DateUtil.date());
        updateById(user);
        return reqCommonParams;
    }

    @Override
    public UserDto login(HttpServletRequest request, String code) {
        String realIp = HttpUtils.getRealIp(request);
        JSONObject wx = WeChatUtils.code2Session(code);
        String openId = wx.getString("openid");
        List<User> userList = list(new QueryWrapper<User>().eq("open_id", openId));
        if (CollUtil.isNotEmpty(userList)) {
            User user = userList.get(userList.size() - 1);
            user.setLastActiveTime(DateUtil.date());
            user.setLastActiveIp(realIp);
            updateById(user);
            UserToken userToken = userTokenService.list(new QueryWrapper<UserToken>().eq("user_id", user.getId()))
                .stream().findFirst().orElse(null);
            List<UserCompany> userCompanyList = userCompanyService.listUserCompanyId(user.getId());
            Integer companyId = userCompanyList.stream().filter(UserCompany::getCurrentFlag)
                .map(UserCompany::getCompanyId).findFirst().orElse(MiniConstant.DEFAULT_COMPANY_ID);
            if (userToken != null) {
                userToken.setExpireDate(DateUtil.offsetWeek(DateUtil.date(), 2));
                userTokenService.updateById(userToken);
                return new UserDto(user, companyId, userToken.getToken());
            } else {
                String my_token = RandomUtil.randomString(32);
                String token = JavaHashHmac.getSignature(my_token);
                UserToken newUserToken = new UserToken();
                newUserToken.setUserId(user.getId());
                newUserToken.setToken(token);
                newUserToken.setExpireDate(DateUtils.offsetWeek(DateUtils.date(), 2));
                newUserToken.setCreateDate(DateUtils.date());
                userTokenService.save(newUserToken);
                return new UserDto(user, companyId, token);
            }
        }
        User user = new User();
        user.setOpenId(openId);
        user.setNickName(String.format("随机用户_%s", RandomUtil.randomString(6)));
        user.setCreateDate(DateUtils.date());
        user.setLastActiveIp(realIp);
        user.setRegisterIp(realIp);
        user.setLastActiveTime(DateUtils.date());
        save(user);
        //当用户存在时,token为空创建token
        String my_token = RandomUtil.randomString(32);
        String token = JavaHashHmac.getSignature(my_token);
        UserToken userToken = new UserToken();
        userToken.setUserId(user.getId());
        userToken.setToken(token);
        userToken.setExpireDate(DateUtils.offsetWeek(DateUtils.date(), 2));
        userToken.setCreateDate(DateUtils.date());
        userTokenService.save(userToken);
        return new UserDto(user, 0, token);
    }
}




